package android.serialport;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;


import org.greenrobot.eventbus.EventBus;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class SerialPortUtil {
    public static String error;
    public static boolean flag = false;
    public static InputStream inputStream;
    public static boolean isOpen = false;
    public static Context mycontext;
    public static OutputStream outputStream;
    public static Thread receiveThread;
    public static SerialPort serialPort;

    public static String ByteArrayToInt(final byte[] array) {
        String string = "";
        if (array != null) {
            for (final byte b : array) {
                final StringBuilder sb = new StringBuilder();
                sb.append(string);
                sb.append(" ");
                sb.append(b);
                string = sb.toString();
            }
        }
        final StringBuilder sb2 = new StringBuilder();
        sb2.append("ByteArrayToInt:");
        sb2.append(string);
        Log.i("test", sb2.toString());
        return string;
    }

    public static String ByteArrayToString(final byte[] array) {
        final StringBuilder sb = new StringBuilder();
        if (array != null) {
            for (int length = array.length, i = 0; i < length; ++i) {
                sb.append(String.format("%02X ", array[i]));
            }
        }
        return sb.toString();
    }

    public static String bytes2HexString(final byte[] array) {
        String string = "";
        for (int i = 0; i < array.length; ++i) {
            String s = Integer.toHexString(0xFF & array[i]);
            if (s.length() == 1) {
                final StringBuilder sb = new StringBuilder();
                sb.append('0');
                sb.append(s);
                s = sb.toString();
            }
            final StringBuilder sb2 = new StringBuilder();
            sb2.append(string);
            sb2.append(s.toUpperCase());
            string = sb2.toString();
        }
        final StringBuilder sb3 = new StringBuilder();
        sb3.append("bytes2HexString:");
        sb3.append(string);
        Log.i("test", sb3.toString());
        return string;
    }

    public static String bytesToAllHex(final byte[] array, final int n) {
        return new BigInteger(1, array).toString(n);
    }

    public static void closeSerialPort() {
        Log.i("test", "关闭串口");
        try {
            if (SerialPortUtil.inputStream != null) {
                SerialPortUtil.inputStream.close();
            }
            if (SerialPortUtil.outputStream != null) {
                SerialPortUtil.outputStream.close();
            }
            SerialPortUtil.flag = false;
            SerialPortUtil.isOpen = false;
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public static String decode(final String s) {
        final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(s.length() / 2);
        for (int i = 0; i < s.length(); i += 2) {
            byteArrayOutputStream.write("0123456789abcdef".indexOf(s.charAt(i)) << 4 | "0123456789abcdef".indexOf(s.charAt(i + 1)));
        }
        return new String(byteArrayOutputStream.toByteArray());
    }

    public static void openSrialPort(final Context mycontext) {
        SerialPortUtil.mycontext = mycontext;
        Log.i("test", "打开串口");
        try {
            SerialPortUtil.serialPort = new SerialPort(new File("/dev/ttyS3"), 9600, 0, SerialPortUtil.mycontext);
            SerialPortUtil.inputStream = SerialPortUtil.serialPort.getInputStream();
            SerialPortUtil.outputStream = SerialPortUtil.serialPort.getOutputStream();
            SerialPortUtil.isOpen = SerialPortUtil.serialPort.getFlag();
            SerialPortUtil.flag = SerialPortUtil.serialPort.getFlag();
            if (SerialPortUtil.isOpen) {
//                Toast.makeText(mycontext,"打开串口成功",Toast.LENGTH_LONG).show();
                receiveSerialPort();
                return;
            }
            SerialPortUtil.error = SerialPortUtil.serialPort.getError();
        } catch (IOException ex) {
            SerialPortUtil.error = ex.getMessage();
            ex.printStackTrace();
            Toast.makeText(mycontext,SerialPortUtil.error,Toast.LENGTH_LONG).show();

        }
    }

    public static List<Integer> readHex(final byte[] array, final int n) {
        List<Integer> strings = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            String s = Integer.toHexString(0xFF & array[i]);
            if (s.length() == 1) {
                final StringBuilder sb = new StringBuilder();
                sb.append('0');
                sb.append(s);
                s = sb.toString();
            }
            final StringBuilder sb2 = new StringBuilder();
            sb2.append(s.toUpperCase());
            strings.add(Integer.parseInt(sb2.toString(), 16));
        }
        return strings;
    }

    public static String[] readReceive(final byte[] array, final int n) {
//        7bb70d01014b42592d4e3030303141dad0


        final String[] array2 = new String[2];
        String string2;
        String string = string2 = "";
        String string4;
        String string3 = string4 = string2;
        for (int i = 0; i < n; ++i) {
            String s = Integer.toHexString(0xFF & array[i]);
            if (s.length() == 1) {
                final StringBuilder sb = new StringBuilder();
                sb.append('0');
                sb.append(s);
                s = sb.toString();
            }
            if (i < 6) {
                final StringBuilder sb2 = new StringBuilder();
                sb2.append(string);
                sb2.append(s.toUpperCase());
                string = sb2.toString();
            } else if (i < 7) {
                final StringBuilder sb3 = new StringBuilder();
                sb3.append(string3);
                sb3.append(s.toUpperCase());
                string3 = sb3.toString();
            } else if (i < 11) {
                final StringBuilder sb4 = new StringBuilder();
                sb4.append(string2);
                sb4.append(s.toUpperCase());
                string2 = sb4.toString();
            } else {
                final StringBuilder sb5 = new StringBuilder();
                sb5.append(string4);
                sb5.append(s.toUpperCase());
                string4 = sb5.toString();
            }
        }
        if (string.equals("EEB110000100") && string2.equals("FFFCFFFF")) {
            array2[0] = string3;
            array2[1] = string4;
            return array2;
        }
        final StringBuilder sb6 = new StringBuilder();
        sb6.append("head:");
        sb6.append(string);
        Log.i("test", sb6.toString());
        final StringBuilder sb7 = new StringBuilder();
        sb7.append("token:");
        sb7.append(string2);
        Log.i("test", sb7.toString());
        return array2;
    }

    public static void receiveSerialPort() {
        Log.i("test", "接收串口数据");
        if (SerialPortUtil.receiveThread != null) {
            return;
        }
        (SerialPortUtil.receiveThread = new Thread() {

            @Override
            public void run() {
                while (SerialPortUtil.flag) {
                    try {
                        final byte[] array = new byte[1024];
                        if (SerialPortUtil.inputStream == null) {
                            return;
                        }
                        final int read = SerialPortUtil.inputStream.read(array);
                        if (read <= 0 || !SerialPortUtil.flag) {
                            continue;
                        }
                        new String(array, 0, read);
                        final String[] receive = SerialPortUtil.readReceive(array, read);
                        final List<Integer> hex = SerialPortUtil.readHex(array, read);
//                        final String localeString = new Date().toLocaleString();
//                        final StringBuilder sb = new StringBuilder();
//                        sb.append(SerialPortConstants.LOG);
//                        sb.append("接收：");
//                        sb.append(hex);
//                        sb.append("      ");
//                        sb.append(localeString);
//                        sb.append("\n");
//                        SerialPortConstants.LOG = sb.toString();
//                        final Message message = new Message();
//                        final Bundle data = new Bundle();
//                        data.putString("data", hex);
//                        data.putString("cmd", receive[0]);
//                        data.putString("body", receive[1]);
//                        message.setData(data);
                        byte[] data = new byte[read];
                        for (int i = 0; i < read; i++) {
                            data[i] = array[i];
                        }

                        EventBus.getDefault().post(new SerialPortEvent(data,data.length>3?data[3]:-1));
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }).start();
    }

    public static void sendEvent(){
        byte[] data = new byte[]{123, -73, 13, 1, 1, 75, 66, 89, 45, 78, 48, 48, 48, 49, 65, -38, -48};
        EventBus.getDefault().post(new SerialPortEvent(data,data[3]));
    }

    public static void sendSerialPort(final String s) {
        if (!SerialPortUtil.isOpen) {
            Toast.makeText(SerialPortUtil.mycontext, (CharSequence) "系统串口异常", Toast.LENGTH_LONG).show();
            return;
        }
        try {
            final byte[] bytes = s.getBytes();
            SerialPortUtil.outputStream.write(bytes);
            SerialPortUtil.outputStream.flush();
            final String byteArrayToString = ByteArrayToString(bytes);
            final String localeString = new Date().toLocaleString();
            final StringBuilder sb = new StringBuilder();
            sb.append(SerialPortConstants.LOG);
            sb.append("\u53d1\u9001\uff1a");
            sb.append(byteArrayToString);
            sb.append("      ");
            sb.append(localeString);
            sb.append("\n");
            SerialPortConstants.LOG = sb.toString();
        } catch (IOException ex) {
            ex.printStackTrace();
            Log.i("test", "串口数据发送失败");
        }
    }

    public static void sendSerialPortByte(final byte[] array) {
        if (!SerialPortUtil.isOpen) {
            Toast.makeText(mycontext, "系统串口异常", Toast.LENGTH_SHORT).show();
            return;
        }
        try {
            SerialPortUtil.outputStream.write(array);
            SerialPortUtil.outputStream.flush();
            final String byteArrayToString = ByteArrayToString(array);
            final String localeString = new Date().toLocaleString();
            final StringBuilder sb = new StringBuilder();
            sb.append(SerialPortConstants.LOG);
            sb.append("发送");
            sb.append(byteArrayToString);
            sb.append("      ");
            sb.append(localeString);
            sb.append("\n");
            SerialPortConstants.LOG = sb.toString();
        } catch (IOException ex) {
            ex.printStackTrace();
            Log.i("test", "串口数据发送失败");
            Toast.makeText(mycontext,ex.getMessage(),Toast.LENGTH_LONG).show();
        }
    }

}
